package cn.iocoder.yudao.module.resource.common;

import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author 王广帅
 * @version 1.0.0
 * @since 2025/4/28 22:13
 */
@Slf4j
public abstract class MemoryCacheService<K, V extends BaseDO> {

    private LoadingCache<K, V> kvLoadingCache;

    public MemoryCacheService(LmrobotResourceConfig resourceConfig) {
        kvLoadingCache = CacheBuilder.newBuilder().maximumSize(resourceConfig.getCacheMaxSize())
                .expireAfterAccess(Duration.ofMinutes(resourceConfig.getCacheExpireMinute())).build(new CacheLoader<K, V>() {
                    @Override
                    public V load(K key) throws Exception {
                        return loadEntity(key);
                    }
                });
    }


    @NotNull
    protected abstract V loadEntity(K key);

    protected void delete(K key) {
        this.kvLoadingCache.invalidate(key);
    }


    public Collection<V> getFromCacheByKeys(Collection<K> keys) {
        try {
            ImmutableMap<K, V> kvLoadingCacheAll = this.kvLoadingCache.getAll(keys);
            List<V> list = kvLoadingCacheAll.values().stream().filter(c -> c.getCreateTime() != null).toList();
            return list;
        } catch (Exception e) {
            log.warn("查询数据异常,keys: {}", keys, e);
        }
        return Collections.EMPTY_LIST;
    }

    public V getFromCacheByKey(K key) {
        V value = this.kvLoadingCache.getUnchecked(key);
        if (value.getCreateTime() == null) {
            return null;
        }
        return value;
    }
}
